﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Runtime.Serialization.Json;
using System.IO;

namespace SC2Ranks
{
    public class SC2RanksService
    {
        public SC2RanksService(string domain)
        {
            if (string.IsNullOrEmpty(domain))
                throw new ArgumentNullException("domain", "'domain' cannot be null");

            _Domain = domain;
        }

        private string _Domain;  

        public PlayerInfo GetBaseCharacterInfoByCharacterCode(Region region, string characterName, int characterCode)
        {
            string url = string.Format("http://sc2ranks.com/api/base/char/{0}/{1}${2}.json?appKey={3}", Helper.ConvertRegion(region), characterName, characterCode, _Domain);

            return GetDataAndParse<PlayerInfo>(url);
        }

        public PlayerInfo GetBaseCharacterInfoByBNetID(Region region, string characterName, int bnetID)
        {
            string url = string.Format("http://sc2ranks.com/api/base/char/{0}/{1}!{2}.json?appKey={3}", Helper.ConvertRegion(region), characterName, bnetID, _Domain);

            return GetDataAndParse<PlayerInfo>(url);
        }

        public PlayerInfo GetBaseTeamCharacterInfoByCharacterCode(Region region, string characterName, int characterCode)
        {
            string url = string.Format("http://sc2ranks.com/api/base/teams/{0}/{1}${2}.json?appKey={3}", Helper.ConvertRegion(region), characterName, characterCode, _Domain);

            return GetDataAndParse<PlayerInfo>(url);
        }

        public PlayerInfo GetBaseTeamCharacterInfoByBNetID(Region region, string characterName, int bnetID)
        {
            string url = string.Format("http://sc2ranks.com/api/base/teams/{0}/{1}!{2}.json?appKey={3}", Helper.ConvertRegion(region), characterName, bnetID, _Domain);

            return GetDataAndParse<PlayerInfo>(url);        
        }

        public PlayerInfo GetTeamInfoByCharacterCode(Region region, string characterName, int characterCode, int bracket, bool isRandom = false)
        {
            isRandom = bracket == 1 ? false : isRandom;

            string url = string.Format("http://sc2ranks.com/api/char/teams/{0}/{1}${2}/{3}/{4}.json?appKey={5}", Helper.ConvertRegion(region), characterName, characterCode, bracket, isRandom ? 1 : 0, _Domain);

            return GetDataAndParse<PlayerInfo>(url);
        }

        public PlayerInfo GetTeamInfoByBNetID(Region region, string characterName, int bnetID, int bracket, bool isRandom = false)
        {
            isRandom = bracket == 1 ? false : isRandom;

            string url = string.Format("http://sc2ranks.com/api/char/teams/{0}/{1}!{2}/{3}/{4}.json?appKey={5}", Helper.ConvertRegion(region), characterName, bnetID, bracket, isRandom ? 1 : 0, _Domain);

            return GetDataAndParse<PlayerInfo>(url);
        }

        public TeamInfo[] GetCustomDivision(int customDivisionID, Region? region, League? league, int bracket, bool isRandom = false)
        {
            isRandom = bracket == 1 ? false : isRandom;

            string sRegion = region.HasValue ? Helper.ConvertRegion(region.Value) : "all";
            string sLeague = league.HasValue ? Helper.ConvertLeague(league.Value) : "all";

            string url = string.Format("http://sc2ranks.com/api/clist/{0}/{1}/{2}/{3}/{4}.json?appKey={5}", customDivisionID, sRegion, sLeague, bracket, isRandom ? 1 : 0, _Domain);

            return GetDataAndParse<TeamInfo[]>(url);
        }

        public PlayerInfo[] MassGetPlayers(IEnumerable<PlayerSearchInfo> players)
        {
            if (players.Count() > 100)
                throw new ArgumentException("Too many players requested. Max 100 players allowed");

            byte[] bytes = null;
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(PlayerInfo[]));

            string request = Helper.GetSearchRequestBody(players);
            bytes = System.Text.Encoding.UTF8.GetBytes(request);
            
            using (WebClient wc = new WebClient())
            {
                bytes = wc.UploadData(string.Format("http://sc2ranks.com/api/mass/base/char/?appKey={0}", _Domain), "POST", bytes);
            }

            PlayerInfo[] result = null;

            using (MemoryStream ms = new MemoryStream(bytes))
            {
                result = (PlayerInfo[])serializer.ReadObject(ms);
            }

            return result;
        }

        protected T GetDataAndParse<T>(string url) where T: class
        {
            T result = null;
            byte[] jsonBytes = null;

            using (WebClient wc = new WebClient())
            {
                jsonBytes = wc.DownloadData(url);
            }

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));

            using (MemoryStream ms = new MemoryStream(jsonBytes))
            {
                result = (T)serializer.ReadObject(ms);
            }

            return result;
        }
    }
}
